/*
 * Copyright (C) 2012 The MjSip Open Source Project Copyright (C) 2005 Luca Veltri - University of Parma - Italy
 * 
 * This file is part of MjSip (http://www.mjsip.org)
 * 
 * Sipdroid is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
 * 
 * This source code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with this source code; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

package com.cvtt.sip;

import java.util.HashMap;
import java.util.Map;

import android.content.Context;
import android.os.Build;

import com.zoolu.sip.address.NameAddress;
import com.zoolu.sip.provider.SipProvider;
import com.zoolu.sip.provider.SipStack;
import com.zoolu.tools.Configure;
import com.zoolu.tools.Parser;

/**
 * UserProfile maintains the user configuration
 */
public class SIPConfig {

	public static boolean LOG_ENABLE = false;
	
	public static boolean ENCRYPT_ENABLE = false;

	public static final String CONFIG_SERVER = "Server";
	public static final String CONFIG_SERVERADDR = "ServerAddr";
	public static final String CONFIG_SERVERPORT = "ServerPort";
	public static final String CONFIG_SERVERDOMAIN = "ServerDomain";

	public static final String CONFIG_WLAN = "wlan";
	public static final String CONFIG_3G = "3g";
	public static final String CONFIG_EDGE = "edge";

	public static final String CONFIG_FROMUSER = "fromuser";
	public static final String CONFIG_PROTOCOL = "protocol";
	public static final String CONFIG_PORT = "port";

	public static final String CONFIG_KEEPON = "keepon";
	
	//added by zxjh_li 2015-11-27 for kickout
		public static final String KEY_DEVICE_GUID = "device_guid";
	//微话
	/*// Default values of the preferences	
	//public static final String MASTER_SERVER = "114.251.39.52:6060";// 生产环境IP
	public static String MASTER_SERVER = "117.122.192.154:5080";// 生产环境IP
	//public static final String MASTER_SERVERDOMAIN = "sip.95013vh.com";
	public static  String MASTER_SERVERDOMAIN = "sip.95voice.com";
	//public static final int MASTER_SERVERPORT = 6060;
	public static  int MASTER_SERVERPORT = 5080;
	
	//public static final String SLAVE_SERVER = "114.251.39.52:6060";// 生产环境IP
	public static  String SLAVE_SERVER = "114.251.39.18:5080";// 生产环境IP
	//public static final String SLAVE_SERVERDOMAIN = "sip2.95013vh.com";
	public static String SLAVE_SERVERDOMAIN = "sip2.95voice.com";
	public static int SLAVE_SERVERPORT = 6060;
	//public static final int SLAVE_SERVERPORT = 5080;
*/	
		
		//微话+
		public static String MASTER_SERVER = "210.13.82.206:5060";
		public static String MASTER_SERVERDOMAIN = "as1.shangkebao.com";
		public static int MASTER_SERVERPORT = 5060;

		public static String SLAVE_SERVER = "58.32.186.228:5060";
		public static String SLAVE_SERVERDOMAIN = "as2.shangkebao.com";
		public static int SLAVE_SERVERPORT = 5060;
		
	public static final int DEFAULT_LOCALPORT = 5071;
	public static final String DEFAULT_PROTOCOL = "udp";
	
	public static final String DEFAULT_USERNAME = "";
	public static final String DEFAULT_PLAINPASSWD = "";
	public static final String DEFAULT_PASSWORD = "";
	public static final String DEFAULT_FROMUSER = "";
	
	public static final boolean DEFAULT_WLAN = true;
	public static final boolean DEFAULT_3G = true;
	public static final boolean DEFAULT_EDGE = true;
	public static final boolean DEFAULT_VPN = false;
	
	//Added by huah in 2012-11-17
	/* Server Error code*/
	public static int RR_FAILED = -1;
	public static int RR_UNSPECIFIED = 0;
	public static int RR_OK	= 1;
	/** NETWORK */
	public static int RR_CONNECT_FAIL = 0X100;
	public static int RR_TRANSPORT_ERROR = 0X101;
	public static int RR_SERVER_DOWN = 0X102;
	public static int RR_SERVER_BUSY = 0X103;
	public static int RR_INVALID_ADDRESS = 0X104;
	/** PROTOCOL */
	public static int RR_AUTH_FAIL = 0X200;
	public static int RR_VERSION_FAIL = 0X201;
	public static int RR_NOT_FOUND = 0X202;
	public static int RR_DUPLICATE_LOGIN = 0X203;
	public static int RR_REFUSE = 0X204;
	public static int RR_SERVER_INTERNAL_ERROR = 0X205;
	public static int RR_FILTERED = 0X206;
	public static int RR_CAPABILITY_UNSUPPORT = 0X207;
	public static int RR_OFFLINE = 0X208;
	public static int RR_PROTOCOL_ERROR = 0X209;
	public static int RR_CYPHER_UNSUPPORT = 0X20A;
	public static int RR_CODEC_ERROR = 0X20B;
	public static int RR_IGNORED = 0X20C;
	public static int RR_SERVICE_NOT_AVAILABLE = 0X20D;
	public static int RR_INFO_MISSING = 0X20E;
	public static int RR_DURATION_LIMIT = 0X20F;
	public static int RR_INVALID_NUMBER = 0X210;
	public static int RR_SERVER_FULL = 0X211;
	public static int RR_BUSY = 0X212;
	public static int RR_TOO_FREQUENT = 0X213;//过于频繁
	public static int RR_KICKED = 0X214; //被踢下线
	public static int RR_LOCKED = 0X215; //帐号被锁定(冻结)
	public static int RR_BLOCKED = 0X216;
	public static int RR_SERVICE_FORBID = 0X217; //业务禁止
	/** MISC */
	public static int RR_UNKNOWN_ERROR	= 0X300;
	public static int RR_TIMEOUT = 0X301;
	public static int RR_FORWARD = 0X302;
	public static int RR_OUT_OF_BALANCE = 0X303;
	public static int RR_INTERRUPTED = 0X304;
	public static int RR_DEVICE_ERROR = 0X305;
	public static int RR_BALANCE_EXPIRE = 0X306;
	public static int RR_NO_ANSWER = 0X307;
	public static int RR_NOT_CHANGED = 0X308;
	public static int RR_USER_CLIENT_MISMATCH = 0X309; //用户客户端不匹配
	public static int RR_TOO_MANY_CLIENT_PER_COMPUTER = 0X30A;//一台机器登录了太多客户端
	/** FILE */
	public static int RR_FILE_ERROR				= 0X400;
	String uid = "";
					
	public final static Map<Integer, String> callRR = new HashMap<Integer, String>() {

		/**
		 * 
		 */
		private static final long serialVersionUID = -4224780858138596926L;

		{
			put(RR_FAILED,"抱歉，呼叫失败，请检查您呼叫的号码或稍后再试。");
			put(RR_UNSPECIFIED,"抱歉，呼叫失败，请稍后再试。");
			put(RR_BUSY, "抱歉，您呼叫的用户忙，请稍后再试。");
			put(RR_OFFLINE, "抱歉，您呼叫的号码不在线，请稍后再试。");
			put(RR_INVALID_NUMBER,"抱歉，您呼叫的号码无效。");
			put(RR_SERVICE_FORBID, "抱歉，系统暂不支持该业务。");
			put(RR_SERVICE_NOT_AVAILABLE, "抱歉，服务暂不可用，请稍后再试。");
			put(RR_LOCKED, "您的账号已被冻结，如有疑问，请联系客服。");
			put(RR_BLOCKED, "抱歉，您所呼叫的号码因涉及违规操作，已被禁止呼叫。");
			put(RR_TIMEOUT,"抱歉，呼叫超时。");
			put(RR_OUT_OF_BALANCE, "抱歉，您的余额不足，请立即充值或获取更多免费时长后再试。");					
			put(RR_BALANCE_EXPIRE, "抱歉，您的账户余额已过期，请立即充值或获取更多免费时长。");
			put(RR_NO_ANSWER, "抱歉，您呼叫的号码没有应答，请稍后再试。");
			put(RR_TOO_FREQUENT,"抱歉，您所呼叫的号码被禁止呼叫，或因被过于频繁的呼叫而被临时禁止呼叫，请稍后再试。");
		}
	};
	
	
	public static String devMode = "Unkonw";
	/** The default configuration file */

	// ********************** user configurations *********************
	/**
	 * User's AOR (Address Of Record), used also as From URL.
	 * <p/>
	 * The AOR is the SIP address used to register with the user's registrar server (if requested). <br/>
	 * The address of the registrar is taken from the hostport field of the AOR, i.e. the value(s) host[:port] after the '@' character.
	 * <p/>
	 * If not defined (default), it equals the <i>contact_url</i> attribute.
	 */
	public String from_url = null;
	/**
	 * Contact URL. If not defined (default), it is formed by sip:local_user@host_address:host_port
	 */
	public String contact_url = null;
	/** User's name (used to build the contact_url if not explitely defined) */
	public String username = null;
	/** User's realm. */
	public String realm = null;
	/** User's passwd. */
	public String passwd = null;
	
	
	public int refresh_time = 20;
	
	public int restart_time = 30;

	// IMS MMTel settings (added by mandrajg)
	/** q value used at registration */
	public String qvalue = null;
	/** MMTel flavor used */
	public boolean mmtel = false;
	
	// Added by zhh_li 2015-11-27 for kickout
	/** device_guid value used at registration */
	public String device_guid = null;

	/**
	 * Path for the 'ua.jar' lib, used to retrive various UA media (gif, wav, etc.) By default, it is used the "lib/ua.jar" folder
	 */
	public static String ua_jar = "lib/ua.jar";
	/**
	 * Path for the 'contacts.lst' file where save and load the VisualUA contacts By default, it is used the "config/contacts.lst" folder
	 */
	public static String contacts_file = "contacts.lst";

	/** Whether registering with the registrar server */
	public boolean do_register = false;
	/** Whether unregistering the contact address */
	public boolean do_unregister = false;
	/**
	 * Whether unregistering all contacts beafore registering the contact address
	 */
	public boolean do_unregister_all = false;
	/** Expires time (in seconds). */
	public int expires = 3600;

	/**
	 * Rate of keep-alive packets sent toward the registrar server (in milliseconds). Set keepalive_time=0 to disable the sending of keep-alive datagrams.
	 */
	public long keepalive_time = 0;

	/**
	 * Automatic call a remote user secified by the 'call_to' value. Use value 'NONE' for manual calls (or let it undefined).
	 */
	public String call_to = null;
	/**
	 * Automatic answer time in seconds; time<0 corresponds to manual answer mode.
	 */
	public int accept_time = -1;
	/**
	 * Automatic hangup time (call duartion) in seconds; time<=0 corresponds to manual hangup mode.
	 */
	public int hangup_time = -1;
	/**
	 * Automatic call transfer time in seconds; time<0 corresponds to no auto transfer mode.
	 */
	public int transfer_time = -1;
	/**
	 * Automatic re-inviting time in seconds; time<0 corresponds to no auto re-invite mode.
	 */
	public int re_invite_time = -1;

	/**
	 * Redirect incoming call to the secified url. Use value 'NONE' for not redirecting incoming calls (or let it undefined).
	 */
	public String redirect_to = null;

	/**
	 * Transfer calls to the secified url. Use value 'NONE' for not transferring calls (or let it undefined).
	 */
	public String transfer_to = null;

	/** No offer in the invite */
	public boolean no_offer = false;
	/** Do not use prompt */
	public boolean no_prompt = false;

	/** Whether using audio */
	public boolean audio = true; // modified
	/** Whether using video */
	public boolean video = false; // modified

	/** Whether playing in receive only mode */
	public boolean recv_only = false;
	/** Whether playing in send only mode */
	public boolean send_only = false;
	/** Whether playing a test tone in send only mode */
	public boolean send_tone = false;
	/** Audio file to be played */
	public String send_file = null;
	/** Audio file to be recorded */
	public String recv_file = null;

	/** Audio port */
	public int audio_port = 21000;
	// public int[] audio_codecs = {3, 8, 0, 18};
	public int[] audio_codecs = { 18, 8, 0 };
	public int dtmf_avp = 101; // zero means no use of outband DTMF
	/** Audio sample rate */
	public int audio_sample_rate = 8000;
	/** Audio sample size */
	public int audio_sample_size = 1;
	/** Audio frame size */
	public int audio_frame_size = 160;

	/** Video port */
	public int video_port = 21070;
	/** Video avp */
	public int video_avp = 103;
	
	public Context context;

	public static int docked = -1, headset = -1, bluetooth = -1;

	public static boolean on_wlan;

	private static SIPConfig sipConfig = null;

	public static synchronized SIPConfig getInstance(Context ctx) {
		if (sipConfig == null) {
			sipConfig = new SIPConfig(ctx);
		}
		return sipConfig;
	}
	
	public static SIPConfig getSIPConfig() {
		return sipConfig;
	}

	// ************************** Costructors *************************
	/** Costructs a void UserProfile */
	public SIPConfig(Context ctx) {
		context = ctx;
		init();
	}

	/** Inits the UserAgentProfile */
	private void init() {
		devMode = Build.MODEL;
		if (realm == null && contact_url != null)
			realm = new NameAddress(contact_url).getAddress().getHost();
		if (username == null)
			username = (contact_url != null) ? new NameAddress(contact_url)
					.getAddress().getUserName() : "user";
		if (call_to != null && call_to.equalsIgnoreCase(Configure.NONE))
			call_to = null;
		if (redirect_to != null && redirect_to.equalsIgnoreCase(Configure.NONE))
			redirect_to = null;
		if (transfer_to != null && transfer_to.equalsIgnoreCase(Configure.NONE))
			transfer_to = null;
		if (send_file != null && send_file.equalsIgnoreCase(Configure.NONE))
			send_file = null;
		if (recv_file != null && recv_file.equalsIgnoreCase(Configure.NONE))
			recv_file = null;
	}
	
	public void setContext(Context ctx)
	{
		context = ctx;
	}
	
	public Context getContext()
	{
		return context;
	}


	// ************************ Public methods ************************

	/**
	 * Sets contact_url and from_url with transport information.
	 * <p/>
	 * This method actually sets contact_url and from_url only if they haven't still been explicitly initialized.
	 */
	public void initContactAddress(SipProvider sip_provider) { // contact_url
		if (contact_url == null) {
			contact_url = "sip:" + username + "@" + sip_provider.getViaAddress();
			if (sip_provider.getPort() != SipStack.default_port)
				contact_url += ":" + sip_provider.getPort();
			if (!sip_provider.getDefaultTransport().equals(SipProvider.PROTO_UDP))
				contact_url += ";transport=" + sip_provider.getDefaultTransport();
		}
		// from_url
		if (from_url == null)
			from_url = contact_url;
	}

	// *********************** Protected methods **********************

	/** Parses a single line (loaded from the config file) */
	protected void parseLine(String line) {
		String attribute;
		Parser par;
		int index = line.indexOf("=");
		if (index > 0) {
			attribute = line.substring(0, index).trim();
			par = new Parser(line, index + 1);
		}
		else {
			attribute = line;
			par = new Parser("");
		}

		if (attribute.equals("from_url")) {
			from_url = par.getRemainingString().trim();
			return;
		}
		if (attribute.equals("contact_url")) {
			contact_url = par.getRemainingString().trim();
			return;
		}
		if (attribute.equals("username")) {
			username = par.getString();
			return;
		}
		if (attribute.equals("realm")) {
			realm = par.getRemainingString().trim();
			return;
		}
		if (attribute.equals("passwd")) {
			passwd = par.getRemainingString().trim();
			return;
		}
		if (attribute.equals("ua_jar")) {
			ua_jar = par.getStringUnquoted();
			return;
		}
		if (attribute.equals("contacts_file")) {
			contacts_file = par.getStringUnquoted();
			return;
		}

		if (attribute.equals("do_register")) {
			do_register = (par.getString().toLowerCase().startsWith("y"));
			return;
		}
		if (attribute.equals("do_unregister")) {
			do_unregister = (par.getString().toLowerCase().startsWith("y"));
			return;
		}
		if (attribute.equals("do_unregister_all")) {
			do_unregister_all = (par.getString().toLowerCase().startsWith("y"));
			return;
		}
		if (attribute.equals("expires")) {
			expires = par.getInt();
			return;
		}
		if (attribute.equals("keepalive_time")) {
			// keepalive_time = par.getInt();
			keepalive_time = 0;
			return;
		}

		if (attribute.equals("call_to")) {
			call_to = par.getRemainingString().trim();
			return;
		}
		if (attribute.equals("accept_time")) {
			accept_time = par.getInt();
			return;
		}
		if (attribute.equals("hangup_time")) {
			hangup_time = par.getInt();
			return;
		}
		if (attribute.equals("transfer_time")) {
			transfer_time = par.getInt();
			return;
		}
		if (attribute.equals("re_invite_time")) {
			re_invite_time = par.getInt();
			return;
		}
		if (attribute.equals("redirect_to")) {
			redirect_to = par.getRemainingString().trim();
			return;
		}
		if (attribute.equals("transfer_to")) {
			transfer_to = par.getRemainingString().trim();
			return;
		}
		if (attribute.equals("no_offer")) {
			no_offer = (par.getString().toLowerCase().startsWith("y"));
			return;
		}
		if (attribute.equals("no_prompt")) {
			no_prompt = (par.getString().toLowerCase().startsWith("y"));
			return;
		}

		if (attribute.equals("audio")) {
			audio = (par.getString().toLowerCase().startsWith("y"));
			return;
		}
		if (attribute.equals("video")) {
			video = (par.getString().toLowerCase().startsWith("y"));
			return;
		}
		if (attribute.equals("recv_only")) {
			recv_only = (par.getString().toLowerCase().startsWith("y"));
			return;
		}
		if (attribute.equals("send_only")) {
			send_only = (par.getString().toLowerCase().startsWith("y"));
			return;
		}
		if (attribute.equals("send_tone")) {
			send_tone = (par.getString().toLowerCase().startsWith("y"));
			return;
		}
		if (attribute.equals("send_file")) {
			send_file = par.getRemainingString().trim();
			return;
		}
		if (attribute.equals("recv_file")) {
			recv_file = par.getRemainingString().trim();
			return;
		}

		if (attribute.equals("audio_port")) {
			audio_port = par.getInt();
			return;
		}
		if (attribute.equals("audio_sample_rate")) {
			audio_sample_rate = par.getInt();
			return;
		}
		if (attribute.equals("audio_sample_size")) {
			audio_sample_size = par.getInt();
			return;
		}
		if (attribute.equals("audio_frame_size")) {
			audio_frame_size = par.getInt();
			return;
		}
		if (attribute.equals("video_port")) {
			video_port = par.getInt();
			return;
		}
		if (attribute.equals("video_avp")) {
			video_avp = par.getInt();
			return;
		}

		// for backward compatibily
		if (attribute.equals("contact_user")) {
			username = par.getString();
			return;
		}
		if (attribute.equals("auto_accept")) {
			accept_time = ((par.getString().toLowerCase().startsWith("y"))) ? 0 : -1;
			return;
		}
	}
}
